#include "Armor.h"
#include "Game.h"
#include "Renderer.h"
#include "StringLib.h"
#include "Util.h"

Armor::Armor(ArmorType type, MaterialType materialType, ArmorPrefix prefix, ArmorSuffix suffix, bool highQuality) : EquippableItem(GT_IT_ARMOR) {
	m_types[TH_ARMOR_TYPE] = type;
	m_materialType = materialType;
	m_prefix = prefix;
	m_suffix = suffix;
	m_highQuality = highQuality;
	const ArmorInfo& info = g_objectDatabase->getArmorInfo(type);
	m_types[TH_ARMOR_FAMILY] = info.family;
	calculateStats(info);
}

Armor::Armor(std::ifstream& file) : EquippableItem(GT_IT_ARMOR, file) {
	int* tokens = Util::intSplit(file);
	m_types[TH_ARMOR_TYPE] = tokens[0];
	m_prefix = ArmorPrefix(tokens[1]);
	m_suffix = ArmorSuffix(tokens[2]);
	m_materialType = MaterialType(tokens[3]);
	m_highQuality = tokens[4] == 1;
	const ArmorInfo& info = g_objectDatabase->getArmorInfo(ArmorType(tokens[0]));
	m_types[TH_ARMOR_FAMILY] = info.family;
	calculateStats(info);
	m_armor = tokens[5];
	m_dodge = tokens[6];
	delete[] tokens;
}

Armor::~Armor() {
}

void Armor::calculateStats(const ArmorInfo& info) {
	m_weight = info.weight;
	m_defaultArmor = info.armor;
	m_defaultDodge = info.dodge;

	switch(info.family) {
	case AF_HEAD:
		switch(m_materialType) {
		case MT_COPPER:
			break;
		case MT_IRON:
			m_defaultArmor += 2;
			m_weight += m_weight / 10;
			m_defaultDodge -= 1;
			break;
		case MT_BRONZE:
			break;
		case MT_BRASS:
			m_defaultArmor += 1;
			break;
		}
		break;
	case AF_BODY:
		switch(m_materialType) {
		case MT_COPPER:
			break;
		case MT_IRON:
			m_defaultArmor += 3;
			m_defaultDodge -= 2;
			m_weight += m_weight / 10;
			break;
		case MT_BRONZE:
			m_defaultArmor += 1;
			break;
		case MT_BRASS:
			m_defaultArmor += 1;
			m_dodge += 1;
			break;
		}
		break;
	case AF_HANDS:
		switch(m_materialType) {
		case MT_COPPER:
			break;
		case MT_IRON:
			m_defaultArmor += 1;
			m_weight += m_weight / 10;
			break;
		case MT_BRONZE:
			break;
		case MT_BRASS:
			m_defaultArmor += 1;
			break;
		}
		break;
	case AF_LEGS:
		switch(m_materialType) {
		case MT_COPPER:
			break;
		case MT_IRON:
			m_defaultArmor += 2;
			m_weight += m_weight / 10;
			m_defaultDodge -= 1;
			break;
		case MT_BRONZE:
			break;
		case MT_BRASS:
			m_defaultArmor += 1;
			break;
		}
		break;
	case AF_FEET:
		switch(m_materialType) {
		case MT_COPPER:
			break;
		case MT_IRON:
			m_defaultArmor += 1;
			m_weight += m_weight / 10;
			m_defaultDodge -= 1;
			break;
		case MT_BRONZE:
			break;
		case MT_BRASS:
			m_defaultArmor += 1;
			break;
		}
		break;
	}

	m_armor = m_defaultArmor;
	m_dodge = m_defaultDodge;
	if(m_highQuality) {
		m_armor += 2;
		m_dodge += 2;
		m_weight -= m_weight / 10;
	}
}

void Armor::save(std::ofstream& file) const {
	file << getType(TH_GENERIC_TYPE) << "\n";
	EquippableItem::save(file);
	file << getType(TH_ARMOR_TYPE) << " " << m_prefix << " " << m_suffix << " " << m_materialType << " " << (m_highQuality ? 1 : 0) << " " << m_armor << " " << m_dodge << "\n";
}

void Armor::render(float x, float y) {
	g_renderer->render(*this, x, y);
}

std::string Armor::getItemName(int mod) const {
	std::string output = "";
	if(m_statusIdentified)
		output += g_stringLib->getMiscString(MST_STATUS, m_status) + " ";

	if(m_equippableIdentified) {
		if(m_highQuality)
			output += "high quality ";
		if(m_prefix != AP_NONE)
			output += g_stringLib->getMiscString(MST_ARMOR_PREFIX, m_prefix) + " ";
	} else {
		if(isEnchanted())
			output += "enchanted ";
	}
	output += g_stringLib->getMiscString(MST_MATERIAL, m_materialType) + " " + getBasicName();
	if(m_equippableIdentified && m_suffix)
		output += " " + g_stringLib->getMiscString(MST_ARMOR_SUFFIX, m_suffix);
	if(m_equippableIdentified)
		output += " (" + Util::signIntToString(m_dodge) + ", " + Util::signIntToString(m_armor) + ")";
	else
		output += " (" + Util::signIntToString(m_defaultDodge) + ", " + Util::signIntToString(m_defaultArmor) + ")";
	return output;
}

bool Armor::isEnchanted() const {
	return m_prefix != AP_NONE || m_suffix != AS_OF_NONE || m_highQuality;
}


void Armor::logDetails(TextLog& log) const {
	Item::logDetails(log);
	log.addBlankLine();
	log.addLine(g_stringLib->getTextString(ST_ARMOR_DODGE, (m_equippableIdentified ? Util::intToString(m_dodge).c_str() : Util::intToString(m_defaultDodge)).c_str()));
	log.addLine(g_stringLib->getTextString(ST_ARMOR_ARMOR, (m_equippableIdentified ? Util::intToString(m_armor).c_str() : Util::intToString(m_defaultArmor)).c_str()));
	log.addBlankLine();
	log.addLine(g_stringLib->getTextString(ST_ARMOR_MATERIAL, g_stringLib->getObjectString(TH_ARMOR_FAMILY, getType(TH_ARMOR_FAMILY)).c_str(), g_stringLib->getMiscString(MST_MATERIAL, m_materialType).c_str()));
	if(m_equippableIdentified) {
		if(m_highQuality)
			log.addLine(g_stringLib->getTextString(ST_ARMOR_HIGH_QUALITY, g_stringLib->getObjectString(TH_ARMOR_FAMILY, getType(TH_ARMOR_FAMILY)).c_str()));
		if(m_prefix != AP_NONE)
			log.addLine(g_stringLib->getMiscString(MST_ARMOR_PREFIX, m_prefix));
		if(m_suffix != AS_OF_NONE)
			log.addLine(g_stringLib->getMiscString(MST_ARMOR_SUFFIX, m_suffix));
	}
}
